﻿namespace SERFLITEMAX20.Core
{
    using SERFLITEMAX20;
    using System;
    using System.Xml;

    public abstract class UnitBase : BaseObject
    {
        internal float facing;
        internal string name;
        internal float speed;
        internal int unitReactionToPlayer;
        internal float x;
        internal float y;
        internal float z;

        public UnitBase(int ptr, Main sender) : base(ptr, sender)
        {
            this.unitReactionToPlayer = -1;
            this.Update();
        }

        internal int GetUnitFactionByPtr()
        {
            int num = base.sender.Memory.ReadInteger(Addresses.STATIC_g_factionDB);
            int num2 = base.ReadStorageInt(UpdateFields.ITEM_FIELD_ENCHANTMENT_11_3);
            int num3 = base.sender.Memory.ReadInteger(Addresses.STATIC_g_factionGroupDB);
            return base.sender.Memory.ReadInteger(num3 + ((num2 - num) * 4));
        }

        public override XmlElement GetXMLElement(XmlDocument pDom)
        {
            XmlElement xMLElement = base.GetXMLElement(pDom);
            xMLElement.SetAttribute("name", this.Name);
            if (this.Name.IndexOf("?") != -1)
            {
                string name = this.Name;
            }
            xMLElement.SetAttribute("level", this.Level.GetString());
            xMLElement.SetAttribute("x", this.x.GetString());
            xMLElement.SetAttribute("y", this.y.GetString());
            xMLElement.SetAttribute("z", this.z.GetString());
            xMLElement.SetAttribute("facing", this.facing.GetString());
            xMLElement.SetAttribute("flags", this.Flags.GetString());
            xMLElement.SetAttribute("target", this.TargetGUID.GetString());
            xMLElement.SetAttribute("channel", this.ChannelObjectGUID.GetString());
            xMLElement.SetAttribute("summon", this.SummonGuid.GetString());
            xMLElement.SetAttribute("charm", this.CharmGuid.GetString());
            xMLElement.SetAttribute("isdead", this.IsDead.GetString());
            xMLElement.SetAttribute("reaction", this.UnitReactionToPlayer.GetString());
            return xMLElement;
        }

        public override bool Update()
        {
            bool flag = base.Update();
            if (flag)
            {
                this.x = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_UNIT_PosX);
                this.y = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_UNIT_PosY);
                this.z = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_UNIT_PosZ);
                this.facing = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_UNIT_Rotation);
                this.speed = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_UNIT_Speed);
            }
            return flag;
        }

        public override bool CanLoot
        {
            get
            {
                return ((this.DynFlags & 1) != 0);
            }
        }

        public BaseObject CannelObject
        {
            get
            {
                return (BaseObject) base.sender.Objects[this.ChannelObjectGUID];
            }
        }

        internal override long ChannelObjectGUID
        {
            get
            {
                return base.ReadStorageLong(UpdateFields.ITEM_FIELD_SPELL_CHARGES_4);
            }
        }

        public override long CharmGuid
        {
            get
            {
                return base.ReadStorageLong(UpdateFields.OBJECT_END);
            }
        }

        public override int DynFlags
        {
            get
            {
                return base.ReadStorageInt(UpdateFields.CONTAINER_FIELD_SLOT_1_12);
            }
        }

        public override float Facing
        {
            get
            {
                return this.facing;
            }
        }

        public override int Flags
        {
            get
            {
                return base.ReadStorageInt(UpdateFields.ITEM_FIELD_PROPERTY_SEED);
            }
        }

        public override int Health
        {
            get
            {
                return base.ReadStorageInt(UpdateFields.UNIT_FIELD_HEALTH);
            }
        }

        public override float HealthPercentage
        {
            get
            {
                return ((((float) this.Health) / ((float) this.MaximumHealth)) * 100f);
            }
        }

        public override bool IsDead
        {
            get
            {
                return (this.Health == 0);
            }
        }

        public bool IsInCombat
        {
            get
            {
                return ((this.Flags & 0x80000) != 0);
            }
        }

        public override bool IsSitting
        {
            get
            {
                return ((base.ReadStorageInt(UpdateFields.CONTAINER_FIELD_SLOT_1_7) & 0xff) != 0);
            }
        }

        public override int Level
        {
            get
            {
                return base.ReadStorageInt(UpdateFields.UNIT_FIELD_LEVEL);
            }
        }

        public override int MaximumHealth
        {
            get
            {
                return base.ReadStorageInt(UpdateFields.ITEM_FIELD_ENCHANTMENT_4_1);
            }
        }

        public override string Name
        {
            get
            {
                return this.name;
            }
        }

        public UnitBase Pet
        {
            get
            {
                long num = base.ReadStorageLong(UpdateFields.ITEM_FIELD_CONTAINED);
                if (num == 0L)
                {
                    num = base.ReadStorageLong(UpdateFields.OBJECT_END);
                }
                return (UnitBase) base.sender.Objects[num];
            }
        }

        public override float Speed
        {
            get
            {
                return this.speed;
            }
        }

        public override long SummonGuid
        {
            get
            {
                return base.ReadStorageLong(UpdateFields.ITEM_FIELD_CONTAINED);
            }
        }

        public BaseObject Target
        {
            get
            {
                return (BaseObject) base.sender.Objects[this.TargetGUID];
            }
        }

        internal override long TargetGUID
        {
            get
            {
                return base.ReadStorageLong(UpdateFields.ITEM_FIELD_SPELL_CHARGES_2);
            }
        }

        public override int UnitReactionToPlayer
        {
            get
            {
                if (this.unitReactionToPlayer == -1)
                {
                    this.unitReactionToPlayer = base.sender.GetUnitReaction(this, base.sender.Player);
                }
                return this.unitReactionToPlayer;
            }
        }

        public override float X
        {
            get
            {
                return this.x;
            }
        }

        public override float Y
        {
            get
            {
                return this.y;
            }
        }

        public override float Z
        {
            get
            {
                return this.z;
            }
        }
    }
}

